package com.itheima.d7_tcp4;

import java.io.*;
import java.net.Socket;

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true){
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                    //每读到一个信息，把这个消息分发给全部客户端进行接收。
                    sendMsgToAll(msg);
                } catch (Exception e) {
                    System.out.println("有人下线了：" + socket.getRemoteSocketAddress());

                    //有客户端连接进来就需要往集合中存入socket，那肯定也要在客户端离线后，把这个socket管道给抹掉
                    //并且是静态的集合，所以可以直接用类名访问该集合，然后调用remove方法
                    Server.onLineSockets.remove(socket);

                    dis.close();
                    socket.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendMsgToAll(String msg) throws IOException {
        // 把信息发送给全部在线的socket管道接收。而所有的在线socket通信管道，都在集合中记录了
        for (Socket onLineSocket : Server.onLineSockets) {
            //那就是把消息发送给客户端client，所以要建立一个输出流
            OutputStream os = onLineSocket.getOutputStream();   //有异常直接抛出，然后会被上面的try catch捕获
            //再包装成一个数据输出流
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF("本次发送消息的客户端为： "+onLineSocket.getRemoteSocketAddress()+",内容为： " + msg);
            dos.flush();
            /*
            注意，此时启动的每一个客户端都在不断地往外面发消息。并且，唯一的服务端在收到每一个客户端的消息后都分配了单独的线程处理，
                然后每一个线程都会持续把收到的对应的客户端消息，分发给所有的在线的客户端和自己。
                所以客户端管道除了要对外建立socket管道发消息之外，还需要接收服务端转发的其他客户端的消息
             */
        }
    }
}
